Taqsimlangan vazifalar navbati bo'lgan Celery bo'yicha keng qamrovli qo'llanma, samarali asinxron vazifalarni bajarish uchun Redis integratsiyasining amaliy misollari bilan.
Celery Vazifalar Navbati: Redis Integratsiyasi Orqali Taqsimlangan Vazifalarni Bajarish
Bugungi tobora murakkablashib borayotgan va talabchan ilovalar dunyosida vazifalarni asinxron tarzda bajara olish qobiliyati juda muhim. Celery, kuchli taqsimlangan vazifalar navbati, vaqt talab qiladigan yoki resurs talab qiladigan vazifalarni asosiy ilova oqimidan ajratish uchun mustahkam yechim taklif qiladi. Ko'p qirrali xotiradagi ma'lumotlar tuzilmasi ombori bo'lgan Redis bilan birgalikda Celery fon vazifalarini qayta ishlash uchun yuqori darajada masshtablanadigan va samarali yondashuvni taklif etadi.
Celery nima?
Celery - bu taqsimlangan xabar almashishga asoslangan asinxron vazifalar navbati/ishlar navbati. U asosiy ilova oqimidan tashqarida vazifalarni asinxron (fonda) bajarish uchun ishlatiladi. Bu quyidagilar uchun juda muhim:
- Ilova javobgarligini oshirish: Vazifalarni Celery worker'lariga yuklash orqali, veb-ilovangiz murakkab operatsiyalarni qayta ishlash paytida sezgir bo'lib qoladi va muzlab qolmaydi.
- Masshtablash: Celery vazifalarni bir nechta worker tugunlari bo'ylab taqsimlash imkonini beradi, bu esa kerak bo'lganda ishlov berish quvvatini kengaytirishga yordam beradi.
- Ishonchlilik: Celery vazifalarni qayta urinish va xatolarni qayta ishlashni qo'llab-quvvatlaydi, bu esa nosozliklar yuzaga kelganda ham vazifalarning oxir-oqibat bajarilishini ta'minlaydi.
- Uzoq davom etadigan vazifalarni bajarish: Video transkodlash, hisobotlarni yaratish yoki ko'p sonli elektron xatlarni yuborish kabi ancha vaqt talab qiladigan jarayonlar Celery uchun idealdir.
Nega Celery bilan Redis'dan foydalanish kerak?
Celery turli xabar brokerlarini (RabbitMQ, Redis va boshqalar) qo'llab-quvvatlasa-da, Redis o'zining soddaligi, tezligi va oson sozlanishi tufayli mashhur tanlovdir. Redis Celery uchun ham xabar brokeri (transport), ham ixtiyoriy ravishda natija backend'i vazifasini bajaradi. Redis nima uchun yaxshi mos kelishi quyidagicha:
- Tezlik: Redis xotiradagi ma'lumotlar ombori bo'lib, juda tez xabar almashinuvi va natijalarni olishni ta'minlaydi.
- Soddalik: Redis'ni o'rnatish va sozlash nisbatan oson.
- Barqarorlik (Ixtiyoriy): Redis barqarorlik variantlarini taklif etadi, bu esa broker ishdan chiqqan taqdirda vazifalarni tiklash imkonini beradi.
- Pub/Sub qo'llab-quvvatlashi: Redis'ning "nashr etish/obuna bo'lish" (publish/subscribe) imkoniyatlari Celery'ning xabar almashish arxitekturasiga juda mos keladi.
Celery'ning asosiy komponentlari
Celery'ning asosiy komponentlarini tushunish vazifalarni samarali boshqarish uchun muhim:
- Celery ilovasi (celery): Celery bilan o'zaro ishlash uchun asosiy kirish nuqtasi. U vazifalar navbatini sozlash va broker hamda natija backend'iga ulanish uchun mas'uldir.
- Vazifalar (Tasks):
@app.taskbilan belgilangan funksiyalar yoki metodlar bo'lib, ular asinxron tarzda bajarilishi kerak bo'lgan ish birliklarini ifodalaydi. - Worker'lar: Vazifalarni bajaradigan jarayonlar. Ishlov berish quvvatini oshirish uchun bir yoki bir nechta mashinada bir nechta worker ishga tushirishingiz mumkin.
- Broker (Xabarlar navbati): Vazifalarni ilovadan worker'larga uzatuvchi vositachi. Redis, RabbitMQ va boshqa xabar brokerlaridan foydalanish mumkin.
- Natija Backend'i (Result Backend): Vazifalar natijalarini saqlaydi. Celery natijalarni saqlash uchun Redis, ma'lumotlar bazalari (PostgreSQL yoki MySQL kabi) yoki boshqa backend'lardan foydalanishi mumkin.
Celery'ni Redis bilan sozlash
Celery'ni Redis bilan sozlash bo'yicha bosqichma-bosqich qo'llanma:
1. Bog'liqliklarni o'rnatish
Birinchi navbatda, pip yordamida Celery va Redis'ni o'rnating:
pip install celery redis
2. Redis Server'ni o'rnatish
redis-server'ni o'rnating. Yo'riqnomalar operatsion tizimingizga qarab farq qiladi. Masalan, Ubuntu'da:
sudo apt update
sudo apt install redis-server
macOS uchun (Homebrew yordamida):
brew install redis
Windows uchun Redis'ni rasmiy Redis veb-saytidan yuklab olishingiz yoki Chocolatey'dan foydalanishingiz mumkin:
choco install redis
3. Celery'ni sozlash
Celery'ni sozlash uchun celeryconfig.py faylini yarating:
# celeryconfig.py
broker_url = 'redis://localhost:6379/0'
result_backend = 'redis://localhost:6379/0'
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
timezone = 'UTC'
enable_utc = True
Tushuntirish:
broker_url: Redis brokerining URL manzilini belgilaydi. Standart Redis porti 6379. `/0` Redis ma'lumotlar bazasi raqamini (0-15) bildiradi.result_backend: Redis natija backend'ining URL manzilini belgilaydi, broker bilan bir xil konfiguratsiyadan foydalanadi.task_serializervaresult_serializer: Vazifalar va natijalar uchun seriyalash usulini JSON'ga o'rnatadi.accept_content: Vazifalar uchun qabul qilinadigan kontent turlarini ro'yxatini ko'rsatadi.timezonevaenable_utc: Vaqt mintaqasi sozlamalarini sozlaydi. Turli serverlar o'rtasida muvofiqlikni ta'minlash uchun UTC'dan foydalanish tavsiya etiladi.
4. Celery ilovasini yaratish
Celery ilovasi va vazifalaringizni aniqlash uchun Python faylini (masalan, tasks.py) yarating:
# tasks.py
from celery import Celery
import time
app = Celery('my_tasks', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0')
app.config_from_object('celeryconfig')
@app.task
def add(x, y):
time.sleep(5) # Uzoq davom etadigan vazifani simulyatsiya qilish
return x + y
@app.task
def send_email(recipient, subject, body):
# Elektron pochta yuborishni simulyatsiya qilish
print(f"Sending email to {recipient} with subject '{subject}' and body '{body}'")
time.sleep(2)
return f"Email sent to {recipient}"
Tushuntirish:
Celery('my_tasks', broker=...): 'my_tasks' nomli Celery ilovasini yaratadi va broker hamda backend'ni URL'lar yordamida sozlaydi. Shu bilan bir qatorda, agar siz ularni faqatapp.config_from_object('celeryconfig')yordamida sozlasangiz, `broker` va `backend` argumentlarini qoldirib ketishingiz mumkin.@app.task: Oddiy Python funksiyasini Celery vazifasiga aylantiruvchi dekorator.add(x, y): Ikki sonni qo'shadigan va uzoq davom etadigan operatsiyani simulyatsiya qilish uchun 5 soniya uxlaydigan oddiy vazifa.send_email(recipient, subject, body): Elektron pochta yuborishni simulyatsiya qiladi. Haqiqiy holatda, bu elektron pochta serveriga ulanish va xat yuborishni o'z ichiga oladi.
5. Celery Worker'ni ishga tushirish
Terminalni oching va tasks.py hamda celeryconfig.py fayllari joylashgan katalogga o'ting. Keyin, Celery worker'ni ishga tushiring:
celery -A tasks worker --loglevel=info
Tushuntirish:
celery -A tasks worker: Celery worker'ni ishga tushiradi, Celery ilovangiz va vazifalaringiz aniqlangan modulni (tasks) ko'rsatadi.--loglevel=info: Jurnal darajasini INFO'ga o'rnatadi, bu vazifalarni bajarish haqida batafsil ma'lumot beradi.
6. Vazifalarni yuborish
Boshqa Python skriptida yoki interaktiv qobiqda vazifalarni import qiling va ularni Celery worker'ga yuboring:
# client.py
from tasks import add, send_email
# 'add' vazifasini asinxron yuborish
result = add.delay(4, 5)
print(f"Task ID: {result.id}")
# 'send_email' vazifasini asinxron yuborish
email_result = send_email.delay('user@example.com', 'Hello', 'This is a test email.')
print(f"Email Task ID: {email_result.id}")
# Keyinroq, natijani olishingiz mumkin:
# print(result.get())
Tushuntirish:
add.delay(4, 5):addvazifasini 4 va 5 argumentlari bilan Celery worker'ga yuboradi.delay()usuli vazifani asinxron bajarish uchun ishlatiladi. UAsyncResultobyektini qaytaradi.result.id: Vazifaning unikal ID'sini beradi, bu uning bajarilish jarayonini kuzatish uchun ishlatilishi mumkin.result.get(): Vazifa tugaguncha bloklaydi va natijani qaytaradi. Buni asosiy oqimda ehtiyotkorlik bilan ishlating, chunki bu asinxron vazifalarni qayta ishlash maqsadiga zid keladi.
7. Vazifa holatini kuzatish (Ixtiyoriy)
Vazifalar holatini AsyncResult obyekti yordamida kuzatishingiz mumkin. Vazifa tugagandan so'ng qaytarilgan natijani ko'rish uchun yuqoridagi misolda `result.get()`ni izohdan chiqarib, ishga tushirishingiz kerak bo'ladi yoki boshqa monitoring usulidan foydalaning.
Celery shuningdek, real vaqtda monitoring uchun Flower kabi vositalarni taklif qiladi. Flower - bu Celery uchun veb-asosidagi monitoring va boshqaruv vositasidir.
Flower'ni o'rnatish uchun:
pip install flower
Flower'ni ishga tushirish uchun:
celery -A tasks flower
Flower odatda http://localhost:5555 manzilida ishlaydi. Keyin siz Flower veb-interfeysi orqali vazifa holatini, worker holatini va boshqa Celery metrikalarini kuzatishingiz mumkin.
Celery'ning ilg'or xususiyatlari
Celery vazifalar navbatingizni boshqarish va optimallashtirish uchun keng qamrovli ilg'or xususiyatlarni taklif etadi:
Vazifalarni marshrutlash
Siz vazifalarni ularning nomi, navbatlari yoki boshqa mezonlarga qarab ma'lum worker'larga yo'naltirishingiz mumkin. Bu vazifalarni resurs talablariga yoki ustuvorligiga qarab taqsimlash uchun foydalidir. Bunga celeryconfig.py faylingizda `CELERY_ROUTES` dan foydalanib erishiladi. Masalan:
# celeryconfig.py
CELERY_ROUTES = {
'tasks.add': {'queue': 'priority_high'},
'tasks.send_email': {'queue': 'emails'},
}
Keyin, worker'ingizni ishga tushirayotganda, u tinglashi kerak bo'lgan navbatlarni belgilang:
celery -A tasks worker -Q priority_high,emails --loglevel=info
Vazifalarni rejalashtirish (Celery Beat)
Celery Beat - bu vazifalarni davriy ravishda navbatga qo'yadigan rejalashtiruvchi. U ma'lum vaqt oralig'ida bajarilishi kerak bo'lgan vazifalar uchun ishlatiladi (masalan, kunlik hisobotlar, soatlik zaxira nusxalari). Siz uni celeryconfig.py faylingizda `CELERY_BEAT_SCHEDULE` orqali sozlayapsiz.
# celeryconfig.py
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
'send-daily-report': {
'task': 'tasks.send_email',
'schedule': crontab(hour=7, minute=30), # Har kuni UTC vaqti bilan 7:30 da bajariladi
'args': ('reports@example.com', 'Daily Report', 'Here is the daily report.')
},
}
Celery Beat'ni ishga tushirish uchun:
celery -A tasks beat --loglevel=info
Eslatma: Beat rejalashtirilgan vazifani oxirgi marta qachon bajarganini saqlash uchun joyga muhtoj. U standart ravishda fayl ma'lumotlar bazasidan (celerybeat-schedule) foydalanadi, bu ishlab chiqarish muhiti uchun mos emas. Ishlab chiqarish uchun ma'lumotlar bazasiga asoslangan rejalashtiruvchidan foydalaning (masalan, Redis).
Vazifalarni qayta urinish
Celery muvaffaqiyatsiz vazifalarni avtomatik ravishda qayta urinishi mumkin. Bu vaqtinchalik xatolarni (masalan, tarmoqdagi uzilishlar, ma'lumotlar bazasining vaqtinchalik ishdan chiqishi) bartaraf etish uchun foydalidir. Qayta urinishlar sonini va qayta urinishlar orasidagi kechikishni @app.task dekoratoridagi retry_backoff va max_retries parametrlari yordamida sozlashingiz mumkin.
@app.task(bind=True, max_retries=5, retry_backoff=True)
def my_task(self, arg1, arg2):
try:
# Ehtimoliy muvaffaqiyatsiz operatsiya
result = perform_operation(arg1, arg2)
return result
except Exception as exc:
self.retry(exc=exc, countdown=5) # 5 soniyadan keyin qayta urinish
Tushuntirish:
bind=True: Vazifaga o'zining kontekstiga (jumladan,retryusuliga) kirish imkonini beradi.max_retries=5: Maksimal qayta urinishlar sonini 5 ga o'rnatadi.retry_backoff=True: Qayta urinishlar uchun eksponensial kechikishni yoqadi (har bir qayta urinishda kechikish ortadi). Siz shuningdek `retry_backoff=False` bilan birga `default_retry_delay` argumentidan foydalanib, qat'iy belgilangan kechikishni ko'rsatishingiz mumkin.self.retry(exc=exc, countdown=5): Vazifani 5 soniyadan keyin qayta urinadi. `exc` argumenti muvaffaqiyatsizlikka sabab bo'lgan istisnodir.
Vazifalarni zanjir qilish va ish oqimlari
Celery murakkab ish oqimlarini yaratish uchun vazifalarni bir-biriga zanjir qilish imkonini beradi. Bu boshqa vazifalar natijasiga bog'liq bo'lgan vazifalar uchun foydalidir. Ish oqimlarini aniqlash uchun chain, group va chord primitivlaridan foydalanishingiz mumkin.
Zanjir (Chain): Vazifalarni ketma-ket bajaradi.
from celery import chain
workflow = chain(add.s(4, 4), multiply.s(8))
result = workflow.delay()
print(result.get()) # Natija: 64
Ushbu misolda add.s(4, 4) add vazifasining 4 va 4 argumentlari bilan imzosini yaratadi. Xuddi shunday, multiply.s(8) multiply vazifasining 8 argumenti bilan imzosini yaratadi. chain funksiyasi bu imzolarni birlashtirib, avval add(4, 4) ni bajaradigan, so'ngra natijani (8) multiply(8) ga uzatadigan ish oqimini yaratadi.
Guruh (Group): Vazifalarni parallel ravishda bajaradi.
from celery import group
parallel_tasks = group(add.s(2, 2), multiply.s(3, 3), send_email.s('test@example.com', 'Parallel Tasks', 'Running in parallel'))
results = parallel_tasks.delay()
# Natijalarni olish uchun barcha vazifalar tugashini kuting
for res in results.get():
print(res)
Akkord (Chord): Vazifalar guruhini parallel ravishda bajaradi, so'ngra guruh natijalari bilan qayta chaqiruv vazifasini (callback task) bajaradi. Bu bir nechta vazifa natijalarini jamlash kerak bo'lganda foydalidir.
from celery import group, chord
header = group(add.s(i, i) for i in range(10))
callback = send_email.s('aggregation@example.com', 'Chord Result', 'Here are the aggregated results.')
workflow = chord(header)(callback)
result = workflow.delay()
# Qayta chaqiruv vazifasi (send_email) sarlavhadagi (add) barcha vazifalar tugagandan so'ng bajariladi
# va unga natijalar uzatiladi.
Xatolarni qayta ishlash
Celery xatolarni qayta ishlashning bir necha usulini taqdim etadi:
- Vazifalarni qayta urinish: Yuqorida aytib o'tilganidek, vazifalarni muvaffaqiyatsizlikda avtomatik ravishda qayta urinishga sozlashingiz mumkin.
- Xato bo'yicha qayta chaqiruvlar (Error Callbacks): Vazifa muvaffaqiyatsiz bo'lganda bajariladigan xato qayta chaqiruvlarini aniqlashingiz mumkin. Ular `apply_async`, `delay` da yoki zanjirning bir qismi sifatida `link_error` argumenti bilan belgilanadi.
- Global xatolarni qayta ishlash: Siz Celery'ni monitoring xizmatiga (masalan, Sentry, Airbrake) xato hisobotlarini yuborish uchun sozlashingiz mumkin.
@app.task(bind=True)
def my_task(self, arg1, arg2):
try:
result = perform_operation(arg1, arg2)
return result
except Exception as exc:
# Xatoni jurnalga yozing yoki xato hisobotini yuboring
print(f"Task failed with error: {exc}")
raise
@app.task
def error_handler(request, exc, traceback):
print(f"Task {request.id} failed: {exc}\n{traceback}")
#Foydalanish misoli
my_task.apply_async((1, 2), link_error=error_handler.s())
Celery'ni Redis bilan ishlatish bo'yicha eng yaxshi amaliyotlar
Optimal unumdorlik va ishonchlilikni ta'minlash uchun ushbu eng yaxshi amaliyotlarga rioya qiling:
- Ishonchli Redis serveridan foydalaning: Ishlab chiqarish muhiti uchun to'g'ri monitoring va zaxira nusxalari bilan maxsus Redis serveridan foydalaning. Yuqori darajadagi mavjudlik uchun Redis Sentinel'dan foydalanishni o'ylab ko'ring.
- Redis konfiguratsiyasini sozlang: Ilovangiz ehtiyojlariga qarab Redis konfiguratsiya parametrlarini (masalan, xotira chegaralari, chiqarib tashlash siyosatlari) sozlang.
- Celery worker'larini kuzatib boring: Muammolarni tezda aniqlash va hal qilish uchun Celery worker'laringizning sog'lig'i va unumdorligini kuzatib boring. Monitoring uchun Flower yoki Prometheus kabi vositalardan foydalaning.
- Vazifalarni seriyalashni optimallashtiring: Vazifa argumentlari va natijalarining murakkabligi va hajmiga qarab mos seriyalash usulini (masalan, JSON, pickle) tanlang. Ishonchsiz ma'lumotlar bilan ishlaganda, ayniqsa pickle'dan foydalanganda, xavfsizlik oqibatlariga e'tibor bering.
- Vazifalarni idempotent saqlang: Vazifalaringizning idempotent ekanligiga ishonch hosil qiling, ya'ni ularni bir necha marta bajarish kutilmagan yon ta'sirlarga olib kelmaydi. Bu, ayniqsa, muvaffaqiyatsizlikdan keyin qayta urinilishi mumkin bo'lgan vazifalar uchun muhimdir.
- Istisnolarni to'g'ri boshqaring: Kutilmagan ishdan chiqishlarning oldini olish va xatolar to'g'ri jurnalga yozilishi yoki xabar qilinishini ta'minlash uchun vazifalaringizda to'g'ri xatolarni qayta ishlashni amalga oshiring.
- Virtual muhitlardan foydalaning: Bog'liqliklarni ajratish va ziddiyatlarning oldini olish uchun Python loyihalaringiz uchun har doim virtual muhitlardan foydalaning.
- Celery va Redis'ni yangilab turing: Xatolarni tuzatish, xavfsizlik yamoqlari va unumdorlikni yaxshilashdan foydalanish uchun Celery va Redis'ni muntazam ravishda eng so'nggi versiyalariga yangilang.
- Navbatlarni to'g'ri boshqarish: Turli xil vazifa turlari uchun maxsus navbatlarni belgilang (masalan, yuqori ustuvorlikdagi vazifalar, fonni qayta ishlash vazifalari). Bu sizga vazifalarni yanada samaraliroq ustuvorlashtirish va boshqarish imkonini beradi.
Xalqaro masalalar
Celery'ni xalqaro kontekstlarda ishlatganda, quyidagilarni hisobga oling:
- Vaqt mintaqalari: Celery worker'laringiz va Redis serveringiz to'g'ri vaqt mintaqasi bilan sozlanganligiga ishonch hosil qiling. Turli mintaqalar o'rtasida muvofiqlik uchun UTC'dan foydalaning.
- Mahalliylashtirish: Agar vazifalaringiz mahalliylashtirilgan kontentni qayta ishlash yoki yaratishni o'z ichiga olsa, Celery worker'laringiz kerakli lokal ma'lumotlar va kutubxonalarga ega ekanligiga ishonch hosil qiling.
- Belgilar kodirovkasi: Keng doiradagi belgilarni qo'llab-quvvatlash uchun barcha vazifa argumentlari va natijalari uchun UTF-8 kodirovkasidan foydalaning.
- Ma'lumotlar maxfiyligi qoidalari: Vazifalaringizda shaxsiy ma'lumotlarni qayta ishlashda ma'lumotlar maxfiyligi qoidalarini (masalan, GDPR) yodda tuting. Nozik ma'lumotlarni himoya qilish uchun tegishli xavfsizlik choralarini ko'ring.
- Tarmoq kechikishi: Ilova serveringiz, Celery worker'laringiz va Redis serveringiz o'rtasidagi tarmoq kechikishini hisobga oling, ayniqsa ular turli geografik mintaqalarda joylashgan bo'lsa. Tarmoq konfiguratsiyasini optimallashtiring va unumdorlikni oshirish uchun geografik jihatdan taqsimlangan Redis klasteridan foydalanishni o'ylab ko'ring.
Haqiqiy hayotdan misollar
Quyida Celery va Redis'ning umumiy muammolarni hal qilish uchun qanday ishlatilishi mumkinligiga oid ba'zi real misollar keltirilgan:
- Elektron tijorat platformasi: Buyurtmalarni qayta ishlash, buyurtma tasdiqlarini yuborish, hisob-fakturalarni yaratish va fonda inventarni yangilash.
- Ijtimoiy media ilovasi: Rasm yuklashlarni qayta ishlash, bildirishnomalarni yuborish, shaxsiylashtirilgan lentalarni yaratish va foydalanuvchi ma'lumotlarini tahlil qilish.
- Moliyaviy xizmatlar ilovasi: Tranzaktsiyalarni qayta ishlash, hisobotlarni yaratish, risklarni baholash va ogohlantirishlarni yuborish.
- Ta'lim platformasi: Topshiriqlarni baholash, sertifikatlarni yaratish, kurs eslatmalarini yuborish va talabalar faoliyatini tahlil qilish.
- IoT platformasi: Sensor ma'lumotlarini qayta ishlash, qurilmalarni boshqarish, ogohlantirishlarni yaratish va tizim unumdorligini tahlil qilish. Masalan, aqlli qishloq xo'jaligi stsenariysini ko'rib chiqing. Celery turli mintaqalardagi (masalan, Braziliya, Hindiston, Yevropa) fermer xo'jaliklaridan sensor ko'rsatkichlarini qayta ishlash va ushbu ko'rsatkichlarga asoslangan avtomatlashtirilgan sug'orish tizimlarini ishga tushirish uchun ishlatilishi mumkin.
Xulosa
Celery, Redis bilan birgalikda taqsimlangan vazifalarni qayta ishlash uchun kuchli va ko'p qirrali yechimni taqdim etadi. Vaqt talab qiladigan yoki resurs talab qiladigan vazifalarni Celery worker'lariga yuklash orqali siz ilova javobgarligini, masshtablanishini va ishonchliligini oshirishingiz mumkin. O'zining boy xususiyatlari va moslashuvchan sozlash imkoniyatlari bilan Celery oddiy fon vazifalaridan tortib murakkab ish oqimlarigacha bo'lgan keng doiradagi foydalanish holatlariga moslashtirilishi mumkin. Celery va Redis'ni o'zlashtirish turli va talabchan ish yuklarini bajara oladigan yuqori unumdorlikka ega va masshtablanadigan ilovalarni yaratish imkoniyatini ochadi.